package com.fastjrun.db2doc.service.impl;

import cn.smallbun.screw.core.engine.EngineFileType;
import com.fastjrun.apiworld.service.common.ServiceException;
import com.fastjrun.db2doc.common.CodeMsgEnum;
import com.fastjrun.db2doc.config.AppBean;
import com.fastjrun.db2doc.dao.DBConnectionDao;
import com.fastjrun.db2doc.dto.DBConnectionDTO;
import com.fastjrun.db2doc.entity.DbConnection;
import com.fastjrun.db2doc.helper.DTOToEntityConverter;
import com.fastjrun.db2doc.helper.EntityToVOConverter;
import com.fastjrun.db2doc.service.DBConnectionService;
import com.fastjrun.db2doc.service.Db2DocService;
import com.fastjrun.db2doc.vo.DBConnectionVO;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.dynamic.sql.select.SelectDSLCompleter;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

@Service("dBConnectionService")
@Slf4j
public class DBConnectionServiceImpl implements DBConnectionService {
  @Resource DBConnectionDao dbConnectionDao;

  @Resource Db2DocService db2DocService;

  @Resource AppBean appBean;

  /** 数据库连接列表 */
  @Override
  public List<DBConnectionVO> list() {
    List<DBConnectionVO> dbConnectionVOS =
        dbConnectionDao.select(SelectDSLCompleter.allRows()).stream()
            .map(EntityToVOConverter::convert)
            .collect(Collectors.toList());
    return dbConnectionVOS;
  }

  /** 新增数据库连接 */
  @Override
  public void add(DBConnectionDTO dBConnectionDTO) {
    DbConnection dbConnection = DTOToEntityConverter.convert(dBConnectionDTO);
    dbConnectionDao.insert(dbConnection);
  }

  /** 修改数据库连接 */
  @Override
  public void edit(DBConnectionDTO dBConnectionDTO) {
    DbConnection dbConnection = DTOToEntityConverter.convert(dBConnectionDTO);
    dbConnectionDao.updateByPrimaryKey(dbConnection);
  }

  /** 删除数据库连接 */
  @Override
  public void deleteById(Long id) {
    dbConnectionDao.deleteByPrimaryKey(id);
  }

  @Override
  public void testById(Long id) {
    DbConnection dbConnection = dbConnectionDao.selectByPrimaryKey(id).get();
    // 数据源
    DataSource dataSource = this.convert(dbConnection);

    try {
      Connection connection = dataSource.getConnection();
      //
      if (!connection.isValid(10)) {
        connection.close();
        throw new ServiceException(CodeMsgEnum.CodeMsg_21001);
      }
      connection.close();
    } catch (SQLException e) {
      log.error("", e);
      throw new ServiceException(CodeMsgEnum.CodeMsg_21001);
    }
  }

  /** 导出数据库文档 */
  @Override
  public String export(Long id, String type) {
    // 生成文件配置
    EngineFileType engineFileType = EngineFileType.HTML;
    switch (type) {
      case "doc":
        engineFileType = EngineFileType.WORD;
        break;
      case "md":
        engineFileType = EngineFileType.MD;
        break;
      default:
        break;
    }
    DbConnection dbConnection = dbConnectionDao.selectByPrimaryKey(id).get();
    // 数据源
    DataSource dataSource = this.convert(dbConnection);
    String docName = db2DocService.generatorDoc(dataSource, engineFileType);

    return docName + "." + type;
  }

  private DataSource convert(DbConnection dbConnection) {
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setDriverClassName(dbConnection.getDriver());
    hikariConfig.setJdbcUrl(dbConnection.getUrl());
    hikariConfig.setUsername(dbConnection.getUsername());
    hikariConfig.setPassword(dbConnection.getPassword());
    // 设置可以获取tables remarks信息
    hikariConfig.addDataSourceProperty("useInformationSchema", "true");
    hikariConfig.setMinimumIdle(2);
    hikariConfig.setMaximumPoolSize(5);
    return new HikariDataSource(hikariConfig);
  }
}
